﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SqlServer = DataCoreTechnologies.SqlServer;

namespace DataCoreTechnologies.Scribe.Business.Html
{
    internal class ViewDocument : Document
    {
        #region Internal
        //Constructor
        internal ViewDocument(SqlServer.View view)
        {
            DocumentType = DocumentType.View;
            RootDatabase = view.Schema.Database;
            RootServer = RootDatabase.Server;
            URL = "index." + RootDatabase.Name + "." + view.Schema.Name + @".view." + view.Name + @".html";
            _view = view;
        }
        //Properties
        internal override string DisplayName { get { return _view.Name; } }
        //Methods
        internal override string GetHtml()
        {
            if (_html == "")
            {
                AddDdlCssColors();
                AddCssLine(@"      	.propertyColumn {width: 300px; word-wrap: break-word;}");
                AddCssLine(@"      	.nameColumn {width: 300px; word-wrap: break-word;}");
                AddCssLine(@"      	.typeColumn {width: 15%; word-wrap: break-word;}");
                AddCssLine(@"      	.allowNullsColumn {width: 10%; word-wrap: break-word;}");
                AddCssLine(@"      	.isClusteredColumn {width: 20%; word-wrap: break-word;}");

                AddBodyLine(@"<div id=""mainBody"">");

                string heirarchy = @"<h2 id=""topNav"">Location: <a href=""http://index.html"">" + RootServer.Name +
                    @"</a> . ";
                heirarchy += @"<a href=""http://index." +
                    RootDatabase.Name + @".html"">" + ScrubHtml(RootDatabase.Name) + @"</a> . ";
                
                if (Business.FilterPreferences.ShowSchemasPage) 
                   heirarchy += @"<a href=""http://index." +
                       RootDatabase.Name + @".schemas.html"">" + ScrubHtml(_view.Schema.Name) + @"</a> . ";
                else
                   heirarchy += ScrubHtml(_view.Schema.Name) + @" . ";

                heirarchy += ScrubHtml(_view.Name) + @"</h2>";
                AddBodyLine(heirarchy);
                AddBodyLine(@"<h2 id=""title"">" + ScrubHtml(_view.Name) + @" (View)</h2>");
                
                Boolean evenRow = true;
                #region Lambda
                Func<string, string, string> tableRow = (string property, string value) =>
                {
                    string returnValue = @"<tr class=""""><td>" + property + @"</td><td>";
                    if (evenRow == true)
                        returnValue = returnValue.Replace(@"class=""""", @"class=""evenRow""");
                    else
                        returnValue = returnValue.Replace(@"class=""""", @"class=""oddRow""");

                    if (value == null | value == "")
                        returnValue += @"&nbsp;";
                    else
                        returnValue += value;
                    returnValue += @"</td></tr>";

                    evenRow = !evenRow;
                    return returnValue;
                };
                Func<string, string, string> tableHeader = (string property, string value) =>
                {
                    string returnValue = @"<tr><th>" + property + @"</th><th>";
                    if (value == null | value == "")
                        returnValue += @"&nbsp;";
                    else
                        returnValue += value;
                    returnValue += @"</th></tr>";

                    return returnValue;
                };
                #endregion
                #region Properties
                AddBodyLine(@"<h2>");
                AddBodyLine(@"<img id=""img_propertiesDiv"" src=""" + RootFolderPath + @"minus.jpg""> ");
                AddBodyLine(@"<a href=""javascript:;"" onmousedown=""toggleDiv('propertiesDiv');"">Properties</a>");
                AddBodyLine(@"</h2>");

                AddBodyLine(@"<div id=""propertiesDiv"">");
                AddBodyLine(@"<table>");
                AddBodyLine(@"<tr><th>Property</th><th>Value</th></tr>");
                AddBodyLine(@"<colgroup><col class=""propertyColumn""><col class=""valueColumn""></colgroup>");
                
                AddBodyLine(@"<tr class=""evenRow""><td>Name</td><td>" + ScrubHtml(_view.Name) + @"</td></tr>");
                AddBodyLine(@"<tr><td>Schema</td><td>" + ScrubHtml(_view.Schema.Name) + @"</td></tr>");
                AddBodyLine(@"<tr class=""evenRow""><td>Creation Date</td><td>" + _view.CreateDate.ToString() + @"</td></tr>");
                if (_view.ModifiedDate == null)
                    AddBodyLine(@"<tr><td>Last Modified</td><td>N/A</td></tr>");
                else
                    AddBodyLine(@"<tr><td>Last Modified</td><td>" + _view.ModifiedDate.ToString() + @"</td></tr>");
                AddBodyLine(@"<tr class=""evenRow""><td>Description</td><td>" + ScrubHtml(_view.Description) + @"</td></tr>");
                
                AddBodyLine(@"</table>");
                AddBodyLine(@"</div>");
                #endregion
                #region Columns
                AddBodyLine(@"<h2>");
                AddBodyLine(@"<img id=""img_columnsDiv"" src=""" + RootFolderPath + @"minus.jpg""> ");
                AddBodyLine(@"<a href=""javascript:;"" onmousedown=""toggleDiv('columnsDiv');"">Columns</a>");
                AddBodyLine(@"</h2>");

                AddBodyLine(@"<div id=""columnsDiv"">");
                AddBodyLine(@"<table>");
                AddBodyLine(@"<tr><th>Name</th><th>Type</th><th>Allow Nulls</th><th>Is Identity</th></tr>");
                string columnHeader = @"<colgroup><col class=""nameColumn""><col class=""typeColumn"">" +
                    @"<col class=""allowNullsColumn""><col class=""identityColumn"">" +
                    @"</colgroup>";
                AddBodyLine(columnHeader);

                evenRow = true;
                foreach (SqlServer.Column column in _view.Columns)
                {
                    string row = "";
                    row = evenRow == true ? @"<tr class=""evenRow"">" : @"<tr>";
                    evenRow = !evenRow;

                    row += @"<td>" + ScrubHtml(column.Name) + @"</td>";
                    row += @"<td>" + ScrubHtml(DisplayColumn(column)) + @"</td>";
                    row += @"<td>" + column.IsNullable.ToString() + @"</td>";
                    row += @"<td>" + column.IsPrimaryKey + @"</td>";
                    row += @"</tr>";
                    AddBodyLine(row);
                }
                AddBodyLine(@"</table>");
                AddBodyLine(@"</div>");
                #endregion
                #region Triggers
                AddBodyLine(@"<h2>");
                AddBodyLine(@"<img id=""img_triggersDiv"" src=""" + RootFolderPath + @"minus.jpg""> ");
                AddBodyLine(@"<a href=""javascript:;"" onmousedown=""toggleDiv('triggersDiv');"">Triggers</a>");
                AddBodyLine(@"</h2>");

                AddBodyLine(@"<div id=""triggersDiv"">");
                AddBodyLine(@"<table>");
                AddBodyLine(@"<tr><th>Name</th></tr>");
                AddBodyLine(@"<colgroup><col class=""nameColumn""></colgroup>");

                evenRow = true;
                foreach (SqlServer.Trigger trigger in _view.Triggers)
                {
                    string row = evenRow == true ? @"<tr class=""evenRow"">" : @"<tr>";
                    evenRow = !evenRow;
                    
                    if (Business.FilterPreferences.ShowTriggersPage)
                        row += @"<td><a href=""http://index." + RootDatabase.Name
                           + @"." + trigger.View.Schema.Name + "." + trigger.View.Name
                           + @".trigger." + trigger.Name + @".html"">"
                           + ScrubHtml(trigger.Name) + @"</a></td>";
                    else
                       row += @"<td>" + ScrubHtml(trigger.Name) + @"</td>";
                   
                    row += @"</tr>";
                    AddBodyLine(row);
                }

                AddBodyLine(@"</table>");
                AddBodyLine(@"</div>");
                #endregion
                #region Indexes
                AddBodyLine(@"<h2>");
                AddBodyLine(@"<img id=""img_indexesDiv"" src=""" + RootFolderPath + @"minus.jpg""> ");
                AddBodyLine(@"<a href=""javascript:;"" onmousedown=""toggleDiv('indexesDiv');"">Indexes</a>");
                AddBodyLine(@"</h2>");

                AddBodyLine(@"<div id=""indexesDiv"">");
                AddBodyLine(@"<table>");
                AddBodyLine(@"<tr><th>Name</th><th>Is Clustered</th><th>Column(s)</th><th>Description</th></tr>");
                AddBodyLine(@"<colgroup><col class=""nameColumn"" /><col class=""isClusteredColumn"" />" +
                            @"<col class=""columnsColumn"" /><col class=""descriptionColumn"" /></colgroup>");

                evenRow = true;
                foreach (SqlServer.Index index in _view.Indexes)
                {
                    string row = "";
                    row += evenRow == true ? @"<tr class=""evenRow"">" : @"<tr>";
                    evenRow = !evenRow;

                    if (Business.FilterPreferences.ShowIndexesPage)
                       //row += @"<td>" + ScrubHtml(index.Name) + @"</td>";
                       row += @"<td><a href=""http://index." +
                           RootDatabase.Name + @"." + index.View.Schema.Name + "." +
                           index.View.Name + ".index." + index.Name + @".html"">" +
                           ScrubHtml(index.Name) + @"</a></td>";
                    else
                       row += @"<td>" + ScrubHtml(index.Name) + @"</td>";

                    row += @"<td>" + index.Type.ToString() + @"</td>";
                    row += @"<td>&nbsp;";

                    foreach (SqlServer.IndexColumn indexColumn in index.IndexColumns)
                    {
                        row += ScrubHtml(indexColumn.Column.Name);
                        if (indexColumn.IsDescending == true) row += " desc";
                        row += ", ";
                    }
                    row = row.TrimEnd(", ".ToCharArray());
                    row += @"</td>";
                    if (index.Description == "") 
                        row += @"<td>&nbsp;</td>";
                    else
                        row += @"<td>" + ScrubHtml(index.Description) + @"</td>";
                    row += @"</tr>";

                    AddBodyLine(row);
                }
                AddBodyLine(@"</table>");
                AddBodyLine(@"</div>");
                #endregion
                #region Extended Properties
                AddBodyLine(@"<h2>");
                AddBodyLine(@"<img id=""img_extPropertiesDiv"" src=""" + RootFolderPath + @"minus.jpg""> ");
                AddBodyLine(@"<a href=""javascript:;"" onmousedown=""toggleDiv('extPropertiesDiv');"">Extended Properties</a>");
                AddBodyLine(@"</h2>");

                AddBodyLine(@"<div id=""extPropertiesDiv"">");
                AddBodyLine(@"<table>");
                AddBodyLine(@"<tr><th>Name</th><th>Value</th></tr>");
                AddBodyLine(@"<colgroup><col class=""nameColumn""><col class=""valueColumn""></colgroup>");

                evenRow = true;
                foreach (SqlServer.ExtendedProperty extProperty in _view.ExtendedProperties)
                {
                    string row = evenRow == true ? @"<tr class=""evenRow"">" : @"<tr>";
                    evenRow = !evenRow;
                    row += @"<td>" + ScrubHtml(extProperty.Name) + @"</td><td>" + ScrubHtml(extProperty.Value) + @"</td></tr>";
                    AddBodyLine(row);
                }

                AddBodyLine(@"</table>");
                AddBodyLine(@"</div>");
                #endregion
                #region DDL
                AddBodyLine(@"<h2>");
                AddBodyLine(@"<img id=""img_ddl"" src=""" + RootFolderPath + @"minus.jpg""> ");
                AddBodyLine(@"<a href=""javascript:;"" onmousedown=""toggleDiv('ddl');"">DDL</a>");
                AddBodyLine(@"</h2>");

                AddBodyLine(@"<div id=""ddl"">");
                AddBodyLine(@"<table class=""sqlCode"">");

                evenRow = true;
                var codeLines = ColorizeDDL(_view.GetDdlTokens());
                foreach (string codeLine in codeLines)
                {
                    string code = "";
                    if (codeLine == "")
                        code = @"&nbsp;";
                    else
                        code = codeLine;

                    if (evenRow == true)
                        AddBodyLine(@"<tr class=""evenRow""><td>" + code + @"</td></tr>");
                    else
                        AddBodyLine(@"<tr class=""oddRow""><td>" + code + @"</td></tr>");
                    evenRow = !evenRow;
                }
                AddBodyLine(@"</table>");
                AddBodyLine(@"</div>");
                #endregion

                AddBodyLine(@"</div>");
                _html = CreateHtmlDocument();
            }
            return _html;
        }
        #endregion
        #region Private
        private SqlServer.View _view;
        #endregion
    }
}
